package com.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class NioServer {


    private static List<SocketChannel> channelList = new ArrayList<>();

    public void Channel() {
        try {
            //
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(18809));

            // 设置为非阻塞
            serverSocketChannel.configureBlocking(false);
            System.out.println("服务开启，port：18809");

            while (true) {
                SocketChannel socketChannel = serverSocketChannel.accept();
                // 非阻塞情况 socketChannel没有连接就会为空
                if (socketChannel != null) {
                    System.out.println("有链接建立,port:" + socketChannel.socket().getPort());

                    // 再次设置非阻塞，
                    // 若此处不设置非阻塞，后续处理当前连接时程序依旧会等待
                    socketChannel.configureBlocking(false);

                    // 已添加好的连接存于集合中统一管理
                    channelList.add(socketChannel);
                } else {
                    System.out.println("没有人在等人，消耗一会cpu");
                    continue;
                }

                Iterator<SocketChannel> iterator = channelList.iterator();
                while (iterator.hasNext()) {
                    SocketChannel socketChannel1 = iterator.next();
                    if (socketChannel1 == null) {
                        continue;
                    }
                    // 建立缓存区读取连接内容
                    ByteBuffer buf = ByteBuffer.allocate(128);

                    // 若存放连接时未设置非阻塞，此处获取不到数据是程序会阻塞在这里直到获取到数据为止
                    int len = socketChannel1.read(buf);
                    if (len > 0) {

                        System.out.println("" + buf.toString());
                    } else if (len == -1) {
                        // 即连接已经断开，需要删除此链接
                        iterator.remove();
                        System.out.println("断开连接");
                    }
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
        new NioServer().Channel();
    }
}
